package chapter04

import scala.collection.MapView

/**
 * @program lu-scala01
 * @description: 统计单词出现次数
 * @author: zhanglu
 * @create: 2022-04-09 16:21:00
 */
object Lu16_CommonWordCount {

  /**
   * 简单版本实现
   */
  def simple(strList: List[String]): List[(String, Int)] = {
    //1.对字符串进行切分，得到一个打散所有单词的列表
    val wordList = strList.flatMap(_.split(" "))
    println(wordList)
    //2.相同的单词进行分组
    val groupMap: Map[String, List[String]] = wordList.groupBy(word => word)
    println(groupMap)
    //3.对分组之后的list每个单词统计个数'
    val countMap: Map[String, Int] = groupMap.map(kv => (kv._1, kv._2.length))
    //4.将map转换为list并排序取前三
    val sortlist: List[(String, Int)] = countMap.toList
      .sortWith(_._2 > _._2).take(3)
    sortlist
  }

  def complex {
    //预统计的结果
    val strList = List(("hello", 1), ("hello world", 2), ("hello scala", 3),
      ("hello spark from scala", 1), ("hello flink from scala", 2))

    //思路1：直接展开为普通版本
    val newStrList: List[String] = strList.map(kv => (kv._1.trim + " ") * kv._2)
    println("简单版本-统计结果：" +  simple(newStrList))

    //思路2：直接基于预统计结果进行转换
    //将字符串打散为单词，并结合对应的个数包装何曾二元组
    val preCountList: List[(String, Int)] = strList.flatMap(tuple => {
      val s: Array[String] = tuple._1.split(" ")
      val tuples: Array[(String, Int)] = s.map(word => (word, tuple._2))
      tuples
    })
    //对二元组按照单词进行分组
    val countMap: Map[String, List[(String, Int)]] = preCountList.groupBy(_._1)
    println(countMap)
    //叠加每个单词预统计的个数值
    val value1: List[(String, Int)] = countMap.transform(
      (k, tupleList) => tupleList.map(_._2).sum
    ).toList.sortBy(_._2)(Ordering[Int].reverse).take(3)
    println("预统计结果1：" + value1)
    val value2 = countMap.map(kv => (kv._1, kv._2.map(_._2).sum))
      .toList.sortWith(_._2 > _._2).take(3)
    println("预统计结果2：" + value2)

  }

  def main(args: Array[String]): Unit = {
    val strList = List("hello", "hello world", "hello scala", "hello spark from scala", "hello flink from scala")
//    println("简单版本-统计结果：" +  simple(strList))

    complex
  }

}
